/*
 * @Description:Is 工具类
 * @Autor: lcz
 * @LastEditors: lcz
 * @LastEditTime: 2023-10-08 14:17:40
 */
const protoString = Object.prototype.toString;

 class IsUtils {
  static is(val: unknown, type: string): boolean {
    return protoString.call(val) === `[object ${type}]`;
  }

  static isDef<T = unknown>(val?: T): val is T {
    return typeof val != 'undefined';
  }

  static isUnDef<T = unknown>(val?: T): val is T {
    return !IsUtils.isDef(val);
  }

  static isObject(val: unknown): val is Record<any, any> {
    return val !== null && IsUtils.is(val, 'Object');
  }

  static isArray(value: unknown): boolean {
    return Array.isArray(value);
  }

  static isString(value: unknown): boolean {
    return typeof value === 'string';
  }

  static isDate(val: unknown): boolean {
    return IsUtils.is(val, 'Date');
  }

  static isNull(val: unknown): val is null {
    return val === null;
  }

  static isNullAndUnDef(val: unknown): val is null | undefined {
    return IsUtils.isUnDef(val) && IsUtils.isNull(val);
  }

  static isNullOrUnDef(val: unknown): val is null | undefined {
    return IsUtils.isUnDef(val) || IsUtils.isNull(val);
  }

  static isNumber(val: unknown): boolean {
    return IsUtils.is(val, 'Number');
  }

  static isFunction(val: unknown): val is Function {
    return typeof val === 'function';
  }

  static isPromise<T = any>(val: unknown): val is Promise<T> {
    return (
      IsUtils.is(val, 'Promise') &&
      IsUtils.isObject(val) &&
      IsUtils.isFunction(val.then) &&
      IsUtils.isFunction(val.catch)
    );
  }

  static isBoolean(val: unknown): val is boolean {
    return IsUtils.is(val, 'Boolean');
  }

  static isRegExp(val: unknown): val is RegExp {
    return IsUtils.is(val, 'RegExp');
  }

  static isWindow(val: any): val is Window {
    return typeof window !== 'undefined' && IsUtils.is(val, 'Window');
  }

  static isElement(val: unknown): val is Element {
    return IsUtils.isObject(val) && !!val.tagName;
  }

  static isEmpty(val: any): boolean {
    if (IsUtils.isArray(val) || IsUtils.isString(val)) {
      return val.length === 0;
    }

    if (val instanceof Map || val instanceof Set) {
      return val.size === 0;
    }

    if (IsUtils.isObject(val)) {
      return Object.keys(val).length === 0;
    }

    return false;
  }

  static isUrl(path: string): boolean {
    const reg =
      /(((^https?:(?:\/\/)?)(?:[-;:&=+$,\w]+@)?[A-Za-z0-9.-]+(?::\d+)?|(?:www.|[-;:&=+$,\w]+@)[A-Za-z0-9.-]+)((?:\/[+~%/.\w-_]*)?\??(?:[-+=&;%@.\w_]*)#?(?:[\w]*))?)$/;
    return reg.test(path);
  }

  static isImg(fileName: string) {
    const imgTypes = ['jpg', 'png', 'bmp', 'gif', 'svg', 'psd', 'webp'];
    const types = imgTypes.filter((item) => {
      const rex = new RegExp(`.${item}$`);
      return rex.test(fileName);
    });
    return types.length > 0;
  }
}

export default IsUtils;
